"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 14、内置装饰器.py
"""


class MethodsDemo:
    # 类变量 可以实例 self.param_a   和  类 cls.param_a 来调用
    param_a = 0

    # 实例变量
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 类方法@classmathod 在类内可以直接调用类方法或者类变量  参数用cls，可读性强，不能直接调用实例方法和实例变量
    @classmethod
    def classmethod_demo(cls) -> None:
        # 类方法内不能直接调用实例方法和实例变量。需要self本身的参数
        # cls.demo_method()。在类内可以直接调用类方法或者类变量
        cls.classmethod_demo2()
        print('这是一个类方法', cls.param_a)

    @classmethod
    def classmethod_demo2(cls) -> None:
        print('这是一个类方法2', cls.param_a)

    # 正常的实例方法
    def demo_method(self):
        print('这是一个实例方法', self.param_a)

    # 静态方法@staticmethod，静态方法没有 self 和 cls 参数
    @staticmethod
    def static_demo():
        print('这是一个静态方法。作用就是普通的函数，只不过放在类里')


# 在调用中，类和实例都可以直接调用类方法
# 实例方法调用
mc = MethodsDemo('MackJia', 18)
mc.demo_method()  # 这是一个实例方法 0
# 通过实例来调用类方法
mc.classmethod_demo()  # 调用classmethod_demo2的结果：这是一个类方法2 0  和 本身打印的结果：这是一个类方法 0
# 通过实例来调用静态方法
mc.static_demo()  # 这是一个静态方法。作用就是普通的函数，只不过放在类里

# 通过类来调用类方法。无需实例化，直接调用
MethodsDemo.classmethod_demo()  # 调用classmethod_demo2的结果：这是一个类方法2 0  和 本身打印的结果：这是一个类方法 0
# 通过类来调用静态方法
MethodsDemo.static_demo()  # 这是一个静态方法。作用就是普通的函数，只不过放在类里

"""
                  普通方法                   类方法                    静态方法
定义        至少需要一个参数self        至少需要一个参数cls            无默认参数
        
调用        实例名.方法名()             类名.方法名()或                类名.方法名()或
                                        实例名.方法名()                实例名.方法名()

关键字        无                         @classmethod                  @staticmethod

使用场景   方法内部涉及到、            如果需要对类属性，即静态变量    无需类或实例参与
           实例对象属性的操作           进行限制性操作


"""


# 格式化输出时间
class DateFormat:
    def __init__(self, year, mouth, day):
        self.year = year
        self.mouth = mouth
        self.day = day

    def out_date(self):
        print(f'输入的时间为{self.year}年{self.mouth}月{self.day}日')

    # 使用类方法实现json格式输入
    @classmethod
    def json_format(cls, json_data):
        year, mouth, day = json_data['year'], json_data['mouth'], json_data['day']
        return cls(year, mouth, day)


json_data = {'year': 2021, 'mouth': 7, 'day': 1}
# 使用json 格式化 ：类方法
demo = DateFormat.json_format(json_data)
demo.out_date()  # 输入的时间为2021年7月1日

demo = DateFormat(2022, 3, 7)
demo.out_date()  # 输入的时间为2022年3月7日


# 目前需求变更：输入可能是json格式或其他(考虑代码的可扩展性)   每个人调用类时，还得修改
def json_format(json_data):
    year, mouth, day = json_data['year'], json_data['mouth'], json_data['day']
    return year, mouth, day


year, mouth, day = json_format({'year': 2021, 'mouth': 1, 'day': 1})
demo = DateFormat(year, mouth, day)
demo.out_date()


# 静态方法案例    多轮比赛，每轮由两个不同的英雄对打

class Game:

    def __init__(self, first_hero, second_hero):
        self.first_hero = first_hero
        self.second_hero = second_hero

    def fight(self):
        print(f"本论比赛开始，由{self.first_hero} VS {self.second_hero}")

    @staticmethod
    def start():
        print("游戏开始")


Game.start()
game1 = Game("Bob", "Mary")
game1.fight()
